﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using Core;

namespace Service.Agent
{
    class Discover
    {
        internal static List<SqlInstance> EnumerateSqlInstances()
        {
            RegistryKey rk; // used in outer loop
            RegistryKey rk2;  // used in inner loops
            List<SqlInstance> s = new List<SqlInstance>();
            
            // First check the 2005 and higher reg keys
            try
            {
                rk = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL");
                foreach (string key in rk.GetValueNames())
                {
                    SqlInstance sqlInstance = new SqlInstance();
                    string value = rk.GetValue(key).ToString();
                    sqlInstance.Name = key;
                    sqlInstance.Id = value;
                    string cluster = string.Empty;
                    rk2 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Microsoft SQL Server\" + sqlInstance.Id + @"\Cluster");
                    if(rk2 != null)
                        cluster = rk2.GetValue("ClusterName").ToString();

                    if (key.ToLowerInvariant() == "mssqlserver")
                    {
                        if(cluster == string.Empty)
                            sqlInstance.NetworkName = Environment.MachineName;
                        else
                            sqlInstance.NetworkName = cluster;
                        sqlInstance.ServiceName = "mssqlserver";
                    }
                    else
                    {
                        if(cluster == string.Empty)
                            sqlInstance.NetworkName = Environment.MachineName + "\\" + sqlInstance.Name;
                        else
                            sqlInstance.NetworkName = cluster + "\\" + sqlInstance.Name;
                        sqlInstance.ServiceName = "mssql$" + sqlInstance.Name;
                    }


                    rk2 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Microsoft SQL Server\" + sqlInstance.Id + @"\Setup");
                    sqlInstance.ServicePack = Convert.ToInt32(rk2.GetValue("SP"));

                    string version = rk2.GetValue("Version").ToString();
                    if (version.StartsWith("9"))
                        sqlInstance.VersionMajor = 2;
                    if (version.StartsWith("10"))
                        sqlInstance.VersionMajor = 3;
                    if (version.StartsWith("10.5" + sqlInstance.ServicePack.ToString()))
                        sqlInstance.VersionMajor = 4;
                    if (version.StartsWith("11"))
                        sqlInstance.VersionMajor = 5;
                    s.Add(sqlInstance);
                }
            }
            catch (Exception ex)
            {
                Logging.LogInformation(ex.ToString());
            }

            // Now Check the SQL 2000 keys
            try
            {
                rk = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Microsoft SQL Server");
                if (rk != null)
                {
                    string[] servers = (string[])rk.GetValue("InstalledInstances");

                    if (servers.Length > 0)
                    {
                        //Console.WriteLine("#### Searching instances...");
                        Logging.LogInformation("Searching instances...");
                        foreach (string instance in servers)
                        {
                            try
                            {
                                SqlInstance sqlInstance = new SqlInstance();
                                sqlInstance.Name = instance;
                                sqlInstance.Id = instance;
                                string version = "";
                                if (instance.ToLowerInvariant() == "mssqlserver")
                                {
                                    sqlInstance.NetworkName = Environment.MachineName;
                                    rk2 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\MSSQLSERVER\Setup");
                                    if (rk2 != null)
                                        version = rk2.GetValue("PatchLevel", "0").ToString();
                                }
                                else
                                {
                                    sqlInstance.NetworkName = Environment.MachineName + "\\" + instance;
                                    rk2 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft SQL Server\" + instance + @"\Setup");
                                    if (rk2 != null)
                                        version = rk2.GetValue("PatchLevel", "0").ToString();
                                }
                                if (version.StartsWith("8."))
                                {
                                    sqlInstance.VersionMajor = 1;
                                    s.Add(sqlInstance);
                                }
                            }
                            catch (Exception ex)
                            {
                                Logging.LogInformation(ex.ToString());
                            }
                        }
                    }
                }
            }
            catch(Exception ex)
            {
                //Console.WriteLine(ex.ToString());
                Logging.LogError(ex.ToString());
            }
            return s;
        }
    }
}
